#!/usr/bin/python3
# -*- coding: utf-8 -*-

from faker import Faker
from ..models.user import User
from ..repositories.user_repository import UserRepository
from ..utils.id_generator import IdGeneratorSingleton, UuidGenerator
from datetime import datetime
import random
import time

fake = Faker()

class UserService:
    """用户服务类，处理用户相关业务逻辑"""
    
    @classmethod
    def get_user_by_username(cls, username):
        """根据用户名获取用户
        
        Args:
            username: 用户名
            
        Returns:
            User: 用户对象或None
        """
        return UserRepository.get_user_by_username(username)
    
    @classmethod
    def get_user_by_id(cls, user_id, include_extended_info=True):
        """根据用户ID获取用户
        
        Args:
            user_id: 用户ID
            include_extended_info: 是否包含扩展信息(额外的用户属性、统计信息等)
            
        Returns:
            dict: 用户信息字典
        """
        # 从数据库获取基本用户信息
        user = UserRepository.get_user_by_id(user_id)
        
        if not user:
            return None
            
        # 转换为字典，排除敏感字段
        user_dict = user.to_dict(exclude_keys=['password'])
        
        # 如果需要扩展信息，添加额外的用户数据
        if include_extended_info:
            try:
                # 这里可以添加更多用户相关数据，如：
                # - 用户统计信息（登录次数、最后登录时间等）
                # - 用户角色和权限
                # - 用户关联的其他数据
                
                # 示例：添加一些扩展字段（实际项目中应从数据库或其他服务获取）
                user_dict['last_login'] = cls._get_user_last_login(user_id)
                user_dict['roles'] = cls._get_user_roles(user_id)
                user_dict['permissions'] = cls._get_user_permissions(user_id)
                user_dict['statistics'] = cls._get_user_statistics(user_id)
            except Exception:
                # 扩展信息获取失败不应影响基本信息返回
                pass
                
        return user_dict
        
    @classmethod
    def _get_user_last_login(cls, user_id):
        """获取用户最后登录时间（示例方法）"""
        # 实际项目中应从数据库获取
        return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        
    @classmethod
    def _get_user_roles(cls, user_id):
        """获取用户角色（示例方法）"""
        # 实际项目中应从数据库获取
        return ["user"]
        
    @classmethod
    def _get_user_permissions(cls, user_id):
        """获取用户权限（示例方法）"""
        # 实际项目中应从数据库获取
        return ["read", "write"]
        
    @classmethod
    def _get_user_statistics(cls, user_id):
        """获取用户统计信息（示例方法）"""
        # 实际项目中应从数据库获取
        return {
            "login_count": 10,
            "created_items": 5,
            "profile_completion": "80%"
        }
    
    @classmethod
    def create_user(cls, user_data):
        """创建新用户
        
        Args:
            user_data: 用户数据字典
            
        Returns:
            User: 创建的用户对象
            
        Raises:
            ValueError: 创建用户失败时
        """
        # 验证必填字段
        if 'username' not in user_data or not user_data['username']:
            raise ValueError("用户名不能为空")
        
        if 'password' not in user_data or not user_data['password']:
            raise ValueError("密码不能为空")
        
        # 检查用户名是否已存在
        existing_user = cls.get_user_by_username(user_data['username'])
        if existing_user:
            raise ValueError(f"用户名 {user_data['username']} 已存在")
        
        # 补充其他信息
        if 'email' not in user_data or not user_data['email']:
            user_data['email'] = f"{user_data['username']}@example.com"
        
        if 'name' not in user_data or not user_data['name']:
            user_data['name'] = user_data['username']
        
        # 创建用户
        try:
            user = User.from_dict(user_data)
            created_user = UserRepository.create_user(user)
            
            # 移除密码后返回
            user_dict = created_user.to_dict(exclude_keys=['password'])
            return user_dict
        except Exception as e:
            raise ValueError(f"创建用户失败: {str(e)}")
    
    @classmethod
    def update_user(cls, user_data):
        """更新用户信息
        
        Args:
            user_data: 用户数据字典，必须包含user_id字段
            
        Returns:
            dict: 更新后的用户信息字典
            
        Raises:
            ValueError: 更新用户失败时
        """
        if 'user_id' not in user_data or not user_data['user_id']:
            raise ValueError("缺少用户ID")
        
        # 获取现有用户对象
        user_id = user_data.get('user_id')
        existing_user = UserRepository.get_user_by_id(user_id)
        if not existing_user:
            raise ValueError(f"用户ID {user_id} 不存在")
        
        # 如果提供了用户名且不同于原用户名，检查是否有重名
        if 'username' in user_data and user_data['username'] != existing_user.username:
            check_user = cls.get_user_by_username(user_data['username'])
            if check_user:
                raise ValueError(f"用户名 {user_data['username']} 已存在")
        
        # 创建基于现有用户对象的新对象
        existing_user_dict = existing_user.to_dict()
        
        # 只更新用户数据中提供的字段
        for key, value in user_data.items():
            if key in existing_user_dict and key != 'id':  # 不允许修改ID
                existing_user_dict[key] = value
        
        # 创建更新对象
        update_obj = User.from_dict(existing_user_dict)
        
        # 保存更新
        success = UserRepository.update_user(update_obj)
        if not success:
            raise ValueError("更新用户失败")
        
        # 获取更新后的用户信息，不包含扩展字段
        updated_user = UserRepository.get_user_by_id(user_id)
        return updated_user.to_dict(exclude_keys=['password'])
    
    @classmethod
    def authenticate(cls, username, password):
        """用户登录认证
        
        Args:
            username: 用户名
            password: 密码
            
        Returns:
            User: 认证成功的用户，失败返回None
        """
        user = cls.get_user_by_username(username)
        if user and user.password == password:
            return user
        return None
    
    @classmethod
    def get_all_users(cls, limit=100, offset=0):
        """获取所有用户
        
        Args:
            limit: 限制返回数量
            offset: 偏移量
            
        Returns:
            list: 用户信息字典列表
        """
        users = UserRepository.get_all_users(limit, offset)
        return [user.to_dict(exclude_keys=['password']) for user in users]
    
    @classmethod
    def batch_create_users(cls, count, password="password123"):
        """批量创建随机用户
        
        Args:
            count: 创建用户数量
            password: 默认密码
            
        Returns:
            tuple: (成功数量, 失败数量, 成功创建的用户信息列表)
        """
        # 获取现有的用户名、邮箱和用户ID，确保不会重复
        existing_usernames = set()
        existing_emails = set()
        existing_user_ids = set()
        
        conn = UserRepository.get_db_connection()
        cursor = conn.cursor()
        
        try:
            # 获取所有现有用户名
            cursor.execute("SELECT username FROM users")
            for row in cursor.fetchall():
                existing_usernames.add(row[0])
            
            # 获取所有现有邮箱
            cursor.execute("SELECT email FROM users WHERE email IS NOT NULL")
            for row in cursor.fetchall():
                existing_emails.add(row[0])
            
            # 获取所有现有用户ID
            cursor.execute("SELECT user_id FROM users")
            for row in cursor.fetchall():
                existing_user_ids.add(row[0])
        finally:
            conn.close()
        
        # 创建用户列表，确保用户名和邮箱唯一
        users = []
        
        # 获取Faker实例
        fake = Faker()
        
        # 使用基础计数器和随机数，而不是时间延迟
        import random
        base_timestamp = int(datetime.now().timestamp() * 1000)  # 当前毫秒时间戳作为基础
        
        # Gmail的常见域名
        gmail_domains = ['gmail.com', 'googlemail.com']
        
        # 生成ID生成器实例
        id_generator = IdGeneratorSingleton.get_instance()
        
        # 分批处理
        batch_size = 50
        for batch_start in range(0, count, batch_size):
            batch_end = min(batch_start + batch_size, count)
            batch_users = []
            
            for i in range(batch_start, batch_end):
                # 生成唯一后缀，用于确保唯一性
                unique_suffix = f"{i}{random.randint(1000, 9999)}"
                
                # 生成随机姓名，用于邮箱生成
                gender = random.choice(['male', 'female'])
                name = fake.name_male() if gender == 'male' else fake.name_female()
                
                # 使用Faker生成用户名基础
                username_base = fake.user_name()
                
                # 确保用户名唯一
                username = username_base
                counter = 1
                
                # 如果生成的用户名已存在，添加数字后缀或使用唯一后缀
                while username in existing_usernames:
                    if counter < 5:
                        # 先尝试添加数字
                        username = f"{username_base}{counter}"
                    else:
                        # 如果尝试了几次还是重复，使用唯一后缀
                        username = f"{username_base}_{unique_suffix}"
                    counter += 1
                
                # 记录已使用的用户名
                existing_usernames.add(username)
                
                # 创建唯一Gmail邮箱
                # 提取名字部分用于邮箱生成
                name_parts = name.lower().replace(' ', '.').replace('-', '.')
                email_domain = random.choice(gmail_domains)
                
                # 使用多种邮箱模式
                email_options = [
                    # 基于用户名的邮箱
                    f"{username}@{email_domain}",
                    f"{username}{random.randint(1, 999)}@{email_domain}",
                    
                    # 基于姓名的邮箱
                    f"{name_parts}@{email_domain}",
                    f"{name.split()[0].lower()}.{name.split()[-1].lower()}@{email_domain}",
                    f"{name.split()[0][0].lower()}{name.split()[-1].lower()}{random.randint(1, 99)}@{email_domain}"
                ]
                
                # 随机选择一种邮箱模式
                email = random.choice(email_options)
                
                # 确保邮箱唯一
                if email in existing_emails:
                    # 创建一个一定唯一的邮箱
                    email = f"{username}.{unique_suffix}@{email_domain}"
                    
                    # 再次检查唯一性
                    email_counter = 1
                    while email in existing_emails:
                        email = f"{username}_{email_counter}_{unique_suffix}@{email_domain}"
                        email_counter += 1
                
                # 记录已使用的邮箱
                existing_emails.add(email)
                
                # 生成唯一的用户ID
                user_id = None
                max_tries = 10
                tries = 0
                
                while tries < max_tries:
                    # 生成完整的用户ID
                    if isinstance(id_generator, UuidGenerator):
                        user_id = f"USER-{id_generator.next_id()}"
                    else:
                        user_id = f"USER-{id_generator.next_id()}"
                    
                    if user_id not in existing_user_ids:
                        break
                    tries += 1
                
                if tries >= max_tries:
                    print(f"批量创建用户失败: 无法生成唯一用户ID - 跳过创建此用户")
                    continue
                
                # 记录已使用的用户ID
                existing_user_ids.add(user_id)
                
                # 创建用户对象
                user = User(
                    user_id=user_id,
                    username=username,
                    password=password,
                    email=email,
                    name=name,
                    age=random.randint(18, 65),
                    gender=gender,
                    address=fake.address(),
                    phone=fake.phone_number(),
                    birthday=fake.date_of_birth(minimum_age=18, maximum_age=65).strftime("%Y-%m-%d"),
                    company=fake.company(),
                    job=fake.job(),
                    website=fake.url()
                )
                
                batch_users.append(user)
            
            # 批量创建这一批用户
            users.extend(batch_users)
        
        # 批量创建所有用户
        success_count, error_count, successful_users = UserRepository.batch_create_users(users)
        
        # 转换为字典并移除密码
        user_dicts = [user.to_dict(exclude_keys=['password']) for user in successful_users]
        
        return success_count, error_count, user_dicts
    
    @classmethod
    def generate_mock_user(cls, detail_level='full'):
        """生成一个模拟用户信息
        
        Args:
            detail_level: 详细程度，支持'basic'、'full'或'custom'
            
        Returns:
            dict: 模拟用户信息
        """
        gender = random.choice(['male', 'female'])
        
        # 基本字段，始终包含
        basic_info = {
            'id': fake.random_int(min=1000, max=9999),
            'user_id': f"FREYR-{fake.random_int(min=1000000000, max=9999999999)}",
            'username': f"user{fake.random_int(min=10000, max=99999)}",
            'email': fake.email(),
            'name': fake.name_male() if gender == 'male' else fake.name_female(),
        }
        
        # 如果只需要基本信息，直接返回
        if detail_level == 'basic':
            return basic_info
            
        # 扩展个人信息
        extended_info = {
            'age': random.randint(18, 65),
            'gender': gender,
            'address': fake.address(),
            'phone': fake.phone_number(),
            'birthday': fake.date_of_birth(minimum_age=18, maximum_age=65).strftime("%Y-%m-%d"),
            'company': fake.company(),
            'job': fake.job(),
            'website': fake.url(),
            'created_time': fake.date_time_this_year().strftime("%Y-%m-%d %H:%M:%S"),
            'updated_time': fake.date_time_this_month().strftime("%Y-%m-%d %H:%M:%S")
        }
        
        # 额外的高级信息字段
        advanced_info = {
            'avatar': f"https://randomuser.me/api/portraits/{gender}/{random.randint(1, 99)}.jpg",
            'preferences': {
                'theme': random.choice(['light', 'dark', 'system']),
                'notifications': random.choice([True, False]),
                'language': random.choice(['zh-CN', 'en-US', 'ja-JP'])
            },
            'last_login': fake.date_time_this_month().strftime("%Y-%m-%d %H:%M:%S"),
            'statistics': {
                'login_count': random.randint(1, 100),
                'created_items': random.randint(0, 50),
                'profile_completion': f"{random.randint(50, 100)}%"
            },
            'social_media': {
                'twitter': f"https://twitter.com/{fake.user_name()}",
                'facebook': f"https://facebook.com/{fake.user_name()}",
                'instagram': f"https://instagram.com/{fake.user_name()}"
            },
            'roles': ["user"] + (["admin"] if random.random() < 0.1 else []),
            'permissions': ["read", "write"] + (["delete", "admin"] if random.random() < 0.1 else [])
        }
        
        # 根据请求的详细程度组合结果
        result = basic_info.copy()
        
        if detail_level in ['full', 'custom']:
            result.update(extended_info)
            
        if detail_level == 'full':
            result.update(advanced_info)
            
        return result 
    
    @classmethod
    def delete_user(cls, user_id):
        """删除用户
        
        Args:
            user_id: 用户ID
            
        Returns:
            bool: 删除成功返回True，否则返回False
        """
        # 检查用户是否存在
        existing_user = cls.get_user_by_id(user_id)
        if not existing_user:
            return False
        
        # 调用仓储层删除用户
        return UserRepository.delete_user(user_id) 